#!/usr/bin/python

import httplib
import urlparse
import urllib
import base64
from xml.dom import minidom
import sys
import getopt


URLCONNECT = 'http://localhost:8980/'
ONMS_REST = "opennms/rest"
BASE_URI =  "requisitions"
USER="admin"
PASSWD="admin"

class RestData:

	def __init__(self, datatype="form", attributes = {}, **kwargs):

		if kwargs.has_key('element'):
			self._element = kwargs['element']
		else:
			self._element = None
	
		self._attr = attributes
		self._datatype = datatype
		
	def add_attributes(self,attributes):
		for attr in attributes:
			self._attr[attr] = attributes[attr]	
	
	def set_datatype(self, datatype):
		self._datatype = datatype

	def set_element(self, element):
		self._element = element

	def make_form_data(self):
		params = urllib.urlencode( self._attr )
		return params

	def make_xml_data(self):
		doc = minidom.Document()
		node_element = doc.createElement(self._element)
		
		for item in self._attr:
			node_element.setAttribute(item, self._attr[item])

		node_element.setAttribute('xmlns','http://xmlns.opennms.org/xsd/config/model-import')
	
		return node_element.toxml()
		
	def export_data(self):
		data = {}
		if self._datatype == 'xml':
			data['content-type'] = 'application/xml'
			data['data'] = self.make_xml_data()
		if self._datatype == 'form':
			data['content-type'] = 'application/x-www-form-urlencoded'
			data['data'] = self.make_form_data()

		return data	
		

class Connection:
	def __init__(self, base_url, username, password):
		self.base_url = base_url
		self.username = username
		self.password = password
		self.url = urlparse.urlparse(base_url)
		self.data = ""

	def request_get(self, resource, args = None):
		self.request(resource, "get", args)

	def request_post(self, resource, args = None):
		self.request(resource, "post", args)
	
	def request_put(self, resource, args = None):
		self.request(resource, "put", args)

	def request_delete(self, resource, args = None):
		self.request(resource, "delete", args)

	def request(self, resource, method = "get", args = None):
		params = None
		path = resource
		headers = {}

		print args
		if self.username and self.password:
			encoded = base64.encodestring("%s:%s" % (self.username, self.password))[:-1]
			headers["Authorization"] = "Basic %s" % encoded

		if method.upper() == 'POST' or method.upper() == 'PUT':
			if args.has_key('content-type'):
				headers['Content-Type'] = args['content-type']
				headers['Content-Length'] = len(args['data'])


		if (self.url[0] == 'https'):
			conn = httplib.HTTPSConnection(self.url[1])
		else:
			conn = httplib.HTTPConnection(self.url[1])
		
		conn.set_debuglevel(0)
                #print args['data']
                #print headers
                #print method.upper(), "/" + path
	
		req = conn.request(method.upper(), "/" + path, args['data'], headers)
		
		r = conn.getresponse()	
		conn.close()

		self.data = r
		return r

def rest_requisition(action, **kwargs):
	
	options = kwargs['options']
	base_uri = 'requisitions'
	source = options['source']	
	uri = "%s" % (base_uri)
	data = {}
	data['data'] = None

	if action == 'add':
		element = "model-import"
		method = 'post'
		attr = {}
		attr['foreign-source'] = source
		rest = RestData('xml', attr, element=element)
		data = rest.export_data()

	if action == 'remove':
		method = 'delete'
		uri = "%s/%s" % (uri,source)

	if action == 'import':
		method = 'put'
		uri = "%s/%s/deploy" % (uri,source)

	data['uri'] = uri
	data['method'] = method
	
	return data
	
def rest_node(action, **kwargs):
	
	options = kwargs['options']
	if kwargs.has_key('keys'):
		keys = kwargs['keys']
	
	base_uri = 'requisitions'
	source = options['source']	
	id = options['id']	
	label = options['node-label']
	
	uri = "%s/%s/nodes" % (base_uri, source)
	data = { 'data': None }

	if action == 'add':
		method = 'POST'
		element = 'node'
		attr = {}
		attr['foreign-id'] = id
		attr['node-label'] = label
		rest = RestData('xml', attr, element=element)
		data = rest.export_data()

	if action == 'remove':
		method = 'DELETE'
		uri = "%s/%s" % (uri, id)

	if action == 'set':
		method = 'PUT'
		rest = RestData('form', keys)
		data = rest.export_data()
		uri = "%s/%s" % (uri, id)

	data['uri'] = uri
	data['method'] = method

	return data


def rest_interface(action, **kwargs):

	options = kwargs['options']
	if kwargs.has_key('keys'):
		keys = kwargs['keys']
	
	base_uri = 'requisitions'
	source = options['source']	
	id = options['id']	
	ip = options['ip']
	data = { 'data': None }
	
	uri = "%s/%s/nodes/%s/interfaces" % (base_uri, source, id)

	if action == 'add':
		method = 'POST'
		element = 'interface'
		attr = {}
		attr['ip-addr'] = ip
		rest = RestData('xml', attr, element=element)
		data = rest.export_data()
	if action == 'remove':
		method = 'DELETE'
		uri = "%s/%s" % (uri, ip)
		data = {}
	if action == 'set':
		method = 'PUT'
		rest = RestData('form', keys)
		data = rest.export_data()
		uri = "%s/%s" % (uri, ip)
	
	data['uri'] = uri
	data['method'] = method

	return data

def rest_category(action, **kwargs):

	options = kwargs['options']
	if kwargs.has_key('keys'):
		keys = kwargs['keys']
	
	base_uri = 'requisitions'
	source = options['source']	
	id = options['id']	
	category = options['category']
	
	uri = "%s/%s/nodes/%s/categories" % (base_uri, source, id)

	if action == 'add':
		method = 'POST'
		element = 'category'
		attr = {}
		attr['name'] = category
		rest = RestData('xml', attr, element=element)
		data = rest.export_data()
	if action == 'remove':
		method = 'DELETE'
		uri = "%s/%s" % (uri, category)
		data = { 'data': None }
	if action == 'set':
		method = 'PUT'
		rest = RestData('form', keys)
		data = rest.export_data()
		uri = "%s/%s" % (uri, category)
	
	data['uri'] = uri
	data['method'] = method

	return data

def rest_service(action, **kwargs):
	
	options = kwargs['options']
	if kwargs.has_key('keys'):
		keys = kwargs['keys']
	
	base_uri = 'requisitions'
	source = options['source']	
	id = options['id']	
	ip = options['ip']
	service = options['service']
	data = {'data' : None}
	uri = "%s/%s/nodes/%s/interfaces/%s/services" % (base_uri, source, id, ip)

	if action == 'add':
		method = 'post'	
		element = 'monitored-service'
		attr = {}
		attr['foreign-source'] = source
		attr['foreign-id'] = id
		attr['ip-address'] = ip
		attr['service-name'] = service
		rest = RestData('xml', attr, element=element)
		data = rest.export_data()
		
	if action == 'remove':
		method = 'delete'	
		uri = "%s/%s" % (uri, service)

	data['uri'] = uri
	data['method'] = method

	return data

def usage():
	print "onmsprovision.py [-m|--command] [-a|--action] [--ip] [--id] [-g|--group] [-s|--service] [-n|--node-label]"
	print 'example:  ./onmsprovision.py --command=requisition --action=add --group=TWiO'
	print 'example:  ./onmsprovision.py --command=node --action=add --group=TWiO --id=foriegnid1 -n "node 1" '
	print 'example:  ./onmsprovision.py --command=interface --action=add --group=TWiO --id=foriegnid1 --ip=192.168.1.1 '
	print 'example:  ./onmsprovision.py --command=interface --action=set --group=TWiO --id=foriegnid1 --ip=192.168.1.1 --descr="Interface 1" --snmp-primary=P'
	print 'example:  ./onmsprovision.py --command=service --action=add --group=TWiO --id=foriegnid1 --ip=192.168.1.1 --service=ICMP'
	print 'example:  ./onmsprovision.py --command=service --action=add --group=TWiO --id=foriegnid1 --ip=192.168.1.1 --service=SNMP'
 

	print "node options"  
def parse_options(arguments):

	inteface_keys = ['descr=','snmp-primary=','status=']
	node_keys = ['building=','city=','node-label=', 'parent-foreign-id=', 'parent-node-label=' ]
	general_args = ["help","action=","element=","command=", "ip=","id=","group=","service="]

	master_list = general_args+inteface_keys+node_keys	

	try:
		opts, args = getopt.getopt(arguments, "ha:m:i:g:s:n:", master_list)
		if len(opts) < 2:
			usage()
			sys.exit(2)
	except getopt.GetoptError:
		usage()
		sys.exit(2)

	#set options
	options = {}
	keys = {}
	action = None
	command = None

	vals = {}
	for o, a in opts:

		if o in ("-h", "--help"):
			usage()
			sys.exit()
		if o in ("-a", "--action"):
			action = a
		if o in ("-m", "--command"):
			command = a
		if o in ("-i", "--ip"):
			options['ip'] = a
		if o in ("-d", "--id"):
			options['id'] = a	
		if o in ("-g", "--group"):
			options['source'] = a
		if o in ("-s", "--service"):
			options['service'] = a
		if o in ("--node-label"):
			options['node-label'] = a
		
		# Test for Interface Keys	
		if o in ("--descr"):
			keys['descr'] = a
		if o in ("--snmp-primary"):
			keys['snmp-primary'] = a
		if o in ("--status"):
			keys['status'] = a

		#Test for node keys	
		if o in ("--building"):
			keys['building'] = a
		if o in ("--city"):
			keys['city'] = a
		if o in ("--parent-foreign-id"):
			keys['parent-foreign-id'] = a
		if o in ("--parent-node-label"):
			keys['parent-node-label'] = a

	return options, action, command, keys


def process_command(options, action, command, keys, url_connect):

	if command == 'requisition':
		data = rest_requisition(action, options=options)

	if command == 'interface':
		data = rest_interface(action, options=options, keys=keys)

	if command == 'node':
		data = rest_node(action, options=options, keys=keys)

	if command == 'service':
		data = rest_service(action, options=options)

	if command == 'category':
		data = rest_category(action, options=options)
	
	conn = Connection(url_connect, USER, PASSWD)
	print data

	result = conn.request('opennms/rest/%s' % (data['uri']), data['method'], data)
	
	if result.status != 200:
		print "Error: %i" % (result.status)

if __name__=="__main__":

	#ptions, action, command, keys = parse_options(sys.argv[1:])
	#process_command(options, action, command, keys, URLCONNECT)


	url_connect = URLCONNECT

	#Create requistion
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	process_command(options, action, 'requisition', {}, URLCONNECT)

	#sys.exit()	

	#Create Node
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['id'] = 'foreignid1'
	options['node-label'] = 'MIA-DVR1'
	keys = {'building': 'Miami'}
	process_command(options, action, 'node', {}, URLCONNECT)

	#set Node Attribute	
	action = 'set'
	keys = {'building': 'Miami'}
	process_command(options, action, 'node', keys, URLCONNECT)
	
	#Add Interface
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['ip'] = '10.80.4.5'
	options['id'] = 'foreignid1'
	process_command(options, action, 'interface', {}, URLCONNECT)

	#set Interface keys	
	action = 'set'
	keys = {'descr':'Interface 1'}
	process_command(options, action, 'interface', keys, URLCONNECT)

	#Add Category
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['category'] = 'Security'
	options['id'] = 'foreignid1'
	process_command(options, action, 'category', {}, URLCONNECT)
	
	#Add Category
	# add remove set
	action = 'remove'
	options = {}
	options['source'] = "TWiO"
	options['category'] = 'Security'
	options['id'] = 'foreignid1'
	process_command(options, action, 'category', {}, URLCONNECT)
	
	#Add Service
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['ip'] = '10.80.4.5'
	options['id'] = 'foreignid1'
	options['service'] = 'ICMP'
	process_command(options, action, 'service', {}, URLCONNECT)
	

	#Create Node
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['id'] = 'foreignid2'
	options['node-label'] = 'MIA-Panel1'
	keys = {'building': 'Miami'}
	process_command(options, action, 'node', {}, URLCONNECT)

	#set Node Attribute	
	action = 'set'
	keys = {'building': 'Miami'}
	process_command(options, action, 'node', keys, URLCONNECT)
	
	#Add Interface
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['ip'] = '10.80.4.9'
	options['id'] = 'foreignid2'
	process_command(options, action, 'interface', {}, URLCONNECT)

	action = 'set'
	keys = {'descr':'Interface 1'}
	process_command(options, action, 'interface', keys, URLCONNECT)

	#Add Service
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['ip'] = '10.80.4.9'
	options['id'] = 'foreignid2'
	options['service'] = 'ICMP'
	process_command(options, action, 'service', {}, URLCONNECT)
	

	#Create Node
	action = 'add'
	options = { 'source': "TWiO", 'id':'foreignid3', 'node-label' : 'MIA-CAMERA1' }
	keys = {'building': 'Miami'}
	process_command(options, action, 'node', {}, URLCONNECT)


	#set Node Attribute	
	action = 'set'
	keys = {'building': 'Miami'}
	process_command(options, action, 'node', keys, URLCONNECT)
	
	#Add Interface
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['ip'] = '10.80.4.13'
	options['id'] = 'foreignid3'
	process_command(options, action, 'interface', {}, URLCONNECT)

	action = 'set'
	keys = {'descr':'Interface 1'}
	process_command(options, action, 'interface', keys, URLCONNECT)

	#Add Service
	# add remove set
	action = 'add'
	options = {}
	options['source'] = "TWiO"
	options['ip'] = '10.80.4.13'
	options['id'] = 'foreignid3'
	options['service'] = 'ICMP'
	process_command(options, action, 'service', {}, URLCONNECT)
	


